<template>
  <transition name="ai-box">
    <div
      v-if="visible"
      class="ai-float-box"
      :class="{
        dragging: isDragging || isResizing,
        closing: isClosing
      }"
      :style="{
        width: boxSize.width + 'px',
        height: boxSize.height + 'px',
        left: boxPosition.x + 'px',
        top: boxPosition.y + 'px',
        ...customStyle
      }"
    >
      <div class="ai-box-header" @mousedown="startDrag">
        <div class="ai-box-title">
          <el-icon v-if="icon">
            <component :is="icon" />
          </el-icon>
          <span>{{ title }}</span>
          <el-tag v-if="model" type="info" size="small">
            {{ model }}
          </el-tag>
        </div>
        <div class="ai-box-close" @click="handleClose">
          <el-icon><Close /></el-icon>
        </div>
      </div>

      <div class="ai-box-content">
        <!-- 加载状态 -->
        <div v-if="loading" class="ai-loading">
          <el-icon class="is-loading">
            <Loading />
          </el-icon>
          <span>{{ loadingText }}</span>
        </div>
        
        <!-- 错误状态 -->
        <div v-else-if="error" class="ai-error">
          <el-icon><Warning /></el-icon>
          <span>{{ errorText }}</span>
        </div>
        
        <!-- 正常内容 -->
        <div v-else-if="content" class="ai-content">
          <div v-if="useMarkdown" v-html="finalContent"></div>
          <div v-else>{{ finalContent }}</div>
        </div>
        
        <!-- 空状态 -->
        <div v-else class="ai-empty">
          <el-icon><Warning /></el-icon>
          <span>{{ emptyText }}</span>
        </div>
      </div>

      <!-- 拖拽调整大小的手柄 -->
      <div v-if="resizable" class="resize-handle" @mousedown="startResize"></div>
    </div>
  </transition>
</template>

<script setup>
import { ref, computed, watch, onUnmounted } from 'vue'
import { Close, Loading, Warning } from '@element-plus/icons-vue'
import { marked } from 'marked'

// 配置 marked
marked.setOptions({
  breaks: true,
  gfm: true,
  sanitize: false
})

// Props
const props = defineProps({
  // 控制显示/隐藏
  visible: {
    type: Boolean,
    default: false
  },
  // 标题
  title: {
    type: String,
    default: 'AI助手'
  },
  // 图标组件
  icon: {
    type: [String, Object],
    default: null
  },
  // 模型信息
  model: {
    type: String,
    default: ''
  },
  // 内容
  content: {
    type: String,
    default: ''
  },
  // 是否使用Markdown渲染
  useMarkdown: {
    type: Boolean,
    default: true
  },
  // 加载状态
  loading: {
    type: Boolean,
    default: false
  },
  // 加载文本
  loadingText: {
    type: String,
    default: 'AI正在分析...'
  },
  // 错误状态
  error: {
    type: Boolean,
    default: false
  },
  // 错误文本
  errorText: {
    type: String,
    default: '出现错误，请稍后重试'
  },
  // 空状态文本
  emptyText: {
    type: String,
    default: '暂无内容'
  },
  // 初始位置
  initialPosition: {
    type: Object,
    default: () => ({ x: 100, y: 100 })
  },
  // 初始大小
  initialSize: {
    type: Object,
    default: () => ({ width: 400, height: 300 })
  },
  // 最小尺寸
  minSize: {
    type: Object,
    default: () => ({ width: 300, height: 200 })
  },
  // 是否可调整大小
  resizable: {
    type: Boolean,
    default: true
  },
  // 自定义样式
  customStyle: {
    type: Object,
    default: () => ({})
  },
  // 是否启用打字机效果
  enableTypewriter: {
    type: Boolean,
    default: false
  },
  // 打字机效果速度（毫秒）
  typewriterSpeed: {
    type: Number,
    default: 30
  },
  // 是否应该触发打字机效果（用于区分是否有新数据）
  shouldTriggerTypewriter: {
    type: Boolean,
    default: true
  }
})

// Emits
const emit = defineEmits(['update:visible', 'close'])

// Expose methods
defineExpose({
  closeWithAnimation: () => {
    handleClose()
  }
})

// 响应式数据
const isClosing = ref(false)
const boxPosition = ref({ ...props.initialPosition })
const boxSize = ref({ ...props.initialSize })
const isDragging = ref(false)
const isResizing = ref(false)

// 打字机效果相关
const displayedText = ref('')
const typewriterTimer = ref(null)

// 计算属性
const markdownContent = computed(() => {
  if (!props.content || !props.useMarkdown) return props.content
  return marked(props.content)
})

// 最终显示的内容
const finalContent = computed(() => {
  if (props.enableTypewriter && props.shouldTriggerTypewriter) {
    return displayedText.value
  }
  return props.useMarkdown ? markdownContent.value : props.content
})

// 打字机效果函数
const startTypewriter = (text) => {
  if (!text || !props.enableTypewriter) return
  
  // 清除之前的定时器
  if (typewriterTimer.value) {
    clearInterval(typewriterTimer.value)
    typewriterTimer.value = null
  }
  
  displayedText.value = ''
  let index = 0
  // 如果需要markdown渲染，先转换
  const formattedText = props.useMarkdown ? marked(text) : text
  
  typewriterTimer.value = setInterval(() => {
    if (index < formattedText.length) {
      displayedText.value += formattedText[index]
      index++
    } else {
      clearInterval(typewriterTimer.value)
      typewriterTimer.value = null
    }
  }, props.typewriterSpeed)
}

// 停止打字机效果
const stopTypewriter = () => {
  if (typewriterTimer.value) {
    clearInterval(typewriterTimer.value)
    typewriterTimer.value = null
  }
}

// 监听content变化，触发打字机效果
watch(() => props.content, (newContent) => {
  if (props.enableTypewriter && newContent && props.visible && props.shouldTriggerTypewriter) {
    startTypewriter(newContent)
  }
}, { immediate: true })

// 监听visible变化，关闭时停止打字机
watch(() => props.visible, (newVisible) => {
  if (newVisible && props.enableTypewriter && props.content && props.shouldTriggerTypewriter) {
    // 显示时且启用打字机效果且内容存在且应该触发，开始打字机
    startTypewriter(props.content)
  } else if (!newVisible) {
    // 关闭时停止打字机
    stopTypewriter()
    displayedText.value = ''
  }
})


// 关闭处理
const handleClose = () => {
  isClosing.value = true
  stopTypewriter() // 停止打字机效果
  
  setTimeout(() => {
    emit('update:visible', false)
    emit('close')
    setTimeout(() => {
      isClosing.value = false
    }, 350) // 确保动画完成后再重置状态
  }, 100) // 短暂延迟以开始关闭动画
}

// 组件销毁时清理定时器
onUnmounted(() => {
  stopTypewriter()
})

// 拖拽开始
const startDrag = (e) => {
  if (e.target.closest('.ai-box-close')) {
    return
  }

  e.preventDefault()
  e.stopPropagation()

  isDragging.value = true
  const startX = e.clientX
  const startY = e.clientY
  const startLeft = boxPosition.value.x
  const startTop = boxPosition.value.y

  const handleDrag = (e) => {
    if (!isDragging.value) return

    const deltaX = e.clientX - startX
    const deltaY = e.clientY - startY

    const newX = startLeft + deltaX
    const newY = startTop + deltaY

    // 限制在视窗范围内
    const maxX = window.innerWidth - boxSize.value.width
    const maxY = window.innerHeight - boxSize.value.height

    boxPosition.value = {
      x: Math.max(0, Math.min(newX, maxX)),
      y: Math.max(0, Math.min(newY, maxY))
    }
  }

  const stopDrag = () => {
    isDragging.value = false
    document.removeEventListener('mousemove', handleDrag)
    document.removeEventListener('mouseup', stopDrag)
  }

  document.addEventListener('mousemove', handleDrag)
  document.addEventListener('mouseup', stopDrag)
}

// 调整大小开始
const startResize = (e) => {
  e.preventDefault()
  e.stopPropagation()

  isResizing.value = true
  const startX = e.clientX
  const startY = e.clientY
  const startWidth = boxSize.value.width
  const startHeight = boxSize.value.height

  const handleResize = (e) => {
    if (!isResizing.value) return

    const deltaX = e.clientX - startX
    const deltaY = e.clientY - startY

    const newWidth = Math.max(props.minSize.width, startWidth + deltaX)
    const newHeight = Math.max(props.minSize.height, startHeight + deltaY)

    // 确保调整大小时不会超出视窗
    const maxWidth = window.innerWidth - boxPosition.value.x
    const maxHeight = window.innerHeight - boxPosition.value.y

    boxSize.value = {
      width: Math.min(newWidth, maxWidth),
      height: Math.min(newHeight, maxHeight)
    }
  }

  const stopResize = () => {
    isResizing.value = false
    document.removeEventListener('mousemove', handleResize)
    document.removeEventListener('mouseup', stopResize)
  }

  document.addEventListener('mousemove', handleResize)
  document.addEventListener('mouseup', stopResize)
}
</script>

<style lang="scss" scoped>
// AI浮动框动画
.ai-box-enter-active {
  transition: all 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.ai-box-leave-active {
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.ai-box-enter-from {
  opacity: 0;
  transform: scale(0.7) translateY(-30px);
}

.ai-box-leave-to {
  opacity: 0;
  transform: scale(0.8) translateY(20px);
}

// AI浮动框样式
.ai-float-box {
  position: fixed;
  background: white;
  border: 1px solid #e4e7ed;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  z-index: 1000;
  display: flex;
  flex-direction: column;
  min-width: 300px;
  min-height: 200px;
  max-width: 80vw;
  max-height: 80vh;

  // 拖拽时禁用transition
  &.dragging {
    transition: none !important;
  }

  .ai-box-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 16px;
    border-bottom: 1px solid #e4e7ed;
    background: #f8f9fa;
    border-radius: 8px 8px 0 0;
    flex-shrink: 0;
    cursor: move;
    user-select: none;

    .ai-box-title {
      display: flex;
      align-items: center;
      gap: 8px;
      font-weight: 500;
      color: #333;

      .el-icon {
        color: #409eff;
      }

      .el-tag {
        margin-left: 8px;
      }
    }

    .ai-box-close {
      cursor: pointer;
      padding: 4px;
      border-radius: 4px;
      color: #999;
      transition: all 0.2s;

      &:hover {
        background: #f0f0f0;
        color: #666;
      }

      &:active {
        background: #e0e0e0;
        color: #333;
        transform: scale(0.95);
      }

      .el-icon {
        font-size: 16px;
      }
    }
  }

  // 关闭状态样式
  &.closing {
    .ai-box-close {
      background: #ffebee;
      color: #f44336;

      &:hover {
        background: #ffcdd2;
      }
    }
  }

  .ai-box-content {
    flex: 1;
    padding: 16px;
    overflow-y: auto;
    overflow-x: hidden;

    .ai-loading {
      display: flex;
      align-items: center;
      justify-content: center;
      height: 100px;
      color: #409eff;
      font-size: 14px;

      .el-icon {
        margin-right: 8px;
        font-size: 18px;
      }
    }

    .ai-error,
    .ai-empty {
      display: flex;
      align-items: center;
      justify-content: center;
      flex-direction: column;
      height: 100px;
      color: #909399;
      font-size: 14px;

      .el-icon {
        font-size: 32px;
        margin-bottom: 8px;
      }
    }

    .ai-content {
      line-height: 1.6;
      color: #333;

      // Markdown样式
      :deep(p) {
        margin: 12px 0;
        line-height: 1.6;
      }

      :deep(h1), :deep(h2), :deep(h3), :deep(h4), :deep(h5), :deep(h6) {
        margin: 16px 0 12px 0;
        font-weight: 600;
        color: #2c3e50;
      }

      :deep(h1) { font-size: 24px; }
      :deep(h2) { font-size: 20px; }
      :deep(h3) { font-size: 18px; }
      :deep(h4) { font-size: 16px; }

      :deep(code) {
        background: #f1f3f4;
        padding: 2px 6px;
        border-radius: 3px;
        font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
        font-size: 14px;
        color: #2c3e50;
      }

      :deep(pre) {
        background: #f8f9fa;
        border: 1px solid #e9ecef;
        border-radius: 6px;
        padding: 16px;
        overflow-x: auto;
        margin: 16px 0;

        code {
          background: none;
          padding: 0;
        }
      }

      :deep(ul), :deep(ol) {
        padding-left: 24px;
        margin: 12px 0;

        li {
          margin: 8px 0;
        }
      }

      :deep(strong) {
        font-weight: 600;
        color: #2c3e50;
      }
    }
  }

  // 调整大小手柄
  .resize-handle {
    position: absolute;
    bottom: 0;
    right: 0;
    width: 16px;
    height: 16px;
    cursor: se-resize;
    border-radius: 0 0 8px 0;
    background: 
      linear-gradient(-45deg, transparent 40%, #ddd 40%, #ddd 45%, transparent 45%),
      linear-gradient(-45deg, transparent 50%, #ddd 50%, #ddd 55%, transparent 55%),
      linear-gradient(-45deg, transparent 60%, #ddd 60%, #ddd 65%, transparent 65%);
    background-size: 4px 4px, 6px 6px, 8px 8px;
    background-position: 4px 4px, 8px 8px, 12px 12px;

    &:hover {
      background: 
        linear-gradient(-45deg, transparent 40%, #999 40%, #999 45%, transparent 45%),
        linear-gradient(-45deg, transparent 50%, #999 50%, #999 55%, transparent 55%),
        linear-gradient(-45deg, transparent 60%, #999 60%, #999 65%, transparent 65%);
      background-size: 4px 4px, 6px 6px, 8px 8px;
      background-position: 4px 4px, 8px 8px, 12px 12px;
    }
  }
}
</style>
